class Chain

  def with(chainer, &block)
    chainee = @chainee

    Module.new do
      define_method(:chainee, proc{ chainee })
      define_method(:chainer, proc{ chainer })
      define_method(:chain_code, proc{ block })

      def unchained_method; "#{chainee}_without_#{chainer}"; end
      def chained_method; "#{chainee}_with_#{chainer}"; end

      def included(other)
        other.send(:define_method, chained_method, chain_code) unless chain_code.nil?

        other.send(:alias_method, unchained_method, chainee)
        other.send(:alias_method, chainee, chained_method)
      end
    end
  end

  private

  def initialize(chainee)
    @chainee = chainee
  end

end